/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controller.commands;

import controller.BidirectionalHashMap;
import controller.Constants;
import model.graphic.objects.GTrigger;
import model.graphic.objects.GTriggerPort;
import model.graphic.objects.GDispatcher;
import model.graphic.objects.GDispatcherPort;
import model.graphic.objects.Attachment;
import model.graphic.objects.GInput;
import model.graphic.objects.GInputPort;
import model.graphic.objects.GNode;
import model.graphic.objects.GOutputPort;
import model.graphic.objects.GOutput;
import model.graphic.objects.GTransmitterNode;
import model.graphic.objects.RectangleGraphical;
import core.*;
/**
 *
 * @author Jelle
 */
public class AddAttachmentCommand extends BasicCommand {

    private String type;
    private String name = null;
    private Attachment base = null;
    private String ref = null;

    public AddAttachmentCommand(String type) {
        this.type = type;
    }

    public AddAttachmentCommand(String type, String name) {
        this.type = type;
        this.name = name;
    }

    public AddAttachmentCommand(String type, String name, String ref) {
        this.type = type;
        this.ref = ref;
        this.name = name;
    }

    public AddAttachmentCommand(String type, Attachment base) {
        this.type = type;
        this.base = base;
    }

    public static Class getClassFromPort(Attachment h, BidirectionalHashMap syncs){
        GNode g2 = (GNode)h.getBase();
        Node n2 = syncs.get(g2);
        Port p = (Port)n2.getPort(h.getName());
        return ((ValuePort)p).getValueClass();
    }

    @Override
    public void execute() {


        Attachment h = null;
        RectangleGraphical n;
        if (type.equals(Constants.getTriggerportString()) || type.equals("TriggerPort")) {
            n = (RectangleGraphical) gmodel.getSelected();
            h = new GTriggerPort(n, 30, 40, 15);
            GTrigger c = new GTrigger(h, 5);
            if (name != null) {
                h.setName(name);
                c.setName(name);
            }
            c.setBaseColor(n.getBaseColor());
            gmodel.addObject(c);
            gview.add(c);
            gview.setLayer(c, 10, 0);
            h.attach(n);
            h.setBaseColor(n.getBaseColor());
            gmodel.addObject(h);
            gview.add(h);
        } else if (type.equals(Constants.getInputportString()) || type.equals("StdInPort")) {
            n = (RectangleGraphical) gmodel.getSelected();
            h = new GInputPort(n, 30, 40, 15);
            GInput gi = new GInput(h);
            if (name != null) {
                h.setName(name);
                gi.setName(name);
            }
            gi.setBaseColor(n.getBaseColor());
            gmodel.addObject(gi);
            gview.add(gi);
            h.attach(n);
            h.setBaseColor(n.getBaseColor());
            h.setToolTipText(getClassFromPort(h,sync).getSimpleName());
            gmodel.addObject(h);
            gview.add(h);
        } else if (type.equals(Constants.getDispatcherportString()) || type.equals("StdDispatcherPort")) {
            n = (RectangleGraphical) gmodel.getSelected();
            h = new GDispatcherPort(n, 30, 40, 15);
            GDispatcher d = new GDispatcher(h);
            if (name != null) {
                h.setName(name);
                d.setName(name);
            }
            d.setBaseColor(n.getBaseColor());
            gmodel.addObject(d);
            gview.add(d);
            h.setBaseColor(n.getBaseColor());
            h.attach(n);
            gmodel.addObject(h);
            gview.add(h);
        } else if (type.equals(Constants.getOutputportString()) || type.equals("StdOutPort")) {
            n = (RectangleGraphical) gmodel.getSelected();
            h = new GOutputPort(n, 30, 40, 15);
            GOutput triangle = new GOutput(h);
            if (name != null) {
                h.setName(name);
                triangle.setName(name);
            }
            triangle.setBaseColor(n.getBaseColor());
            gmodel.addObject(triangle);
            gview.add(triangle);
            gview.setLayer(triangle, 10, 0);
            h.setBaseColor(n.getBaseColor());
            h.attach(n);
            h.setToolTipText(getClassFromPort(h,sync).getSimpleName());
            gmodel.addObject(h);
            gview.add(h);
        } else if (type.equals(Constants.getDispatcherString())) {
            gmodel.setSelected(base);
            GDispatcherPort gd = (GDispatcherPort) gmodel.getSelected();
            h = new GDispatcher(gd);
            h.setBaseColor(gd.getBaseColor());
            h.setName(base.getName());
            gview.add(h);
            gview.setLayer(h, 10, 0);
            if (((GNode) base.getBase()).isBoxed()) {
                ((GNode) base.getBase()).getBoxNode().addInternalObject(h);
            } else if(GTransmitterNode.class.isAssignableFrom(base.getBase().getClass())){
                ((GTransmitterNode)base.getBase()).getBase().addTransmitterObject(h);
            }else {
                gmodel.addObject(h);
            }
        } else if (type.equals(Constants.getInputString())) {
            h = new GInput(base);
            h.attach(base);
            h.setBaseColor(base.getBaseColor());
            h.setName(base.getName());
            gview.add(h);
            gview.setLayer(h, 10, 0);
            if (((GNode) base.getBase()).isBoxed()) {
                ((GNode) base.getBase()).getBoxNode().addInternalObject(h);
            } else if(GTransmitterNode.class.isAssignableFrom(base.getBase().getClass())){
                ((GTransmitterNode)base.getBase()).getBase().addTransmitterObject(h);
            }else {
                gmodel.addObject(h);
            }
        }else if(type.equals(Constants.getOutputString())){
            h = new GOutput(base);
            h.attach(base);
            h.setBaseColor(base.getBaseColor());
            h.setName(base.getName());
            gview.add(h);
            gview.setLayer(h, 10, 0);
            if (((GNode) base.getBase()).isBoxed()) {
                ((GNode) base.getBase()).getBoxNode().addInternalObject(h);
            } else if(GTransmitterNode.class.isAssignableFrom(base.getBase().getClass())){
                ((GTransmitterNode)base.getBase()).getBase().addTransmitterObject(h);
            }else {
                gmodel.addObject(h);
            }
        }

        gmodel.setModelChanged();
    }
}